//
// Created by ChenJi on 2021/11/13.
//
#include <string.h>
#include "ZigbeeDevice.h"
#include "UartController.h"
#include "AirSensor.h"
#include "BatteryManager.h"
#include "GeneralUserController.h"

uint8_t ZigbeeMessageBuffer[255];
uint8_t Pocket_ZigbeeState[4] = {0xFE, 0x01, 0x02, 0xFF};
uint8_t Pocket_GetZigbeeShortAddress[4] = {0xFE, 0x01, 0x05, 0xFF};


uint8_t waiting_for_ZigbeeState = 0;
uint8_t waiting_for_ZigbeeShortAddress = 0;
uint8_t zigbee_state = 0;
uint16_t LocalShortAddress = 0x0000;

uint32_t DeviceIdentifyID = 0xFFBA0001;
#define DeviceTypeID 1
uint8_t replyPocketBuffer[200];

uint8_t Pocket_Reply_ChangeState_On[2] = {0x01, 0x01};
uint8_t Pocket_Reply_ChangeState_Off[2] = {0x01, 0x00};
uint8_t Pocket_Reply_Pulse[2] = {0xAA, 0x01};
uint8_t Pocket_Invalid_Reply_Request[2] = {0xFF, 0x00};

uint8_t Pocket_Register[2] = {0xFE, 0x01};

uint8_t pocket_len = 0;
uint16_t registerCoolDown = 0;
uint8_t isRegistered = 0;

void ZigbeeInit() {
    updateZigbeeState();
    *replyPocketBuffer = 0x55;
    *(replyPocketBuffer + 1) = 0x5B;
    *(replyPocketBuffer + 2) = LocalShortAddress >> 8;
    *(replyPocketBuffer + 3) = LocalShortAddress;
    *(replyPocketBuffer + 4) = DeviceIdentifyID >> 24;
    *(replyPocketBuffer + 5) = DeviceIdentifyID >> 16;
    *(replyPocketBuffer + 6) = DeviceIdentifyID >> 8;
    *(replyPocketBuffer + 7) = DeviceIdentifyID;
    *(replyPocketBuffer + 8) = DeviceTypeID;

}

void replyToTerminal(uint8_t *dat, uint8_t len) {
    *(replyPocketBuffer + 9) = len;
    memcpy(replyPocketBuffer + 10, dat, len);
    uint32_t sum = 0;
    for (uint8_t i = 0; i < len; i++) {
        sum += *(dat + i);
    }
    *(replyPocketBuffer + 10 + len) = sum;
    ZigbeeSendMessage(0x0000, replyPocketBuffer, len + 11, 1);

}

void updateZigbeeState() {
    waiting_for_ZigbeeState = 1;
    sendMessageUart1_DMA(Pocket_ZigbeeState, 4);
}

void updateZigbeeShortAddress() {
    waiting_for_ZigbeeShortAddress = 1;
    sendMessageUart1_DMA(Pocket_GetZigbeeShortAddress, 4);
}

void ZigbeeSendMessage(uint16_t address, uint8_t *dat, uint8_t len, uint8_t mode) {
    if (!dat) {
        updateZigbeeState();
        return;
    }
    uint8_t index = 0;
    ZigbeeMessageBuffer[index++] = 0xFC;
    ZigbeeMessageBuffer[index++] = len + 4;
    ZigbeeMessageBuffer[index++] = 03;
    ZigbeeMessageBuffer[index++] = mode;
    ZigbeeMessageBuffer[index++] = address >> 8;
    ZigbeeMessageBuffer[index++] = address;
    memcpy(ZigbeeMessageBuffer + index, dat, len);
    index += len;
    pocket_len = index;
    sendMessageUart1_DMA(ZigbeeMessageBuffer, index);
}


void onUart1Message(uint8_t *dat, uint16_t len) {
    if (waiting_for_ZigbeeState) {
        waiting_for_ZigbeeState = 0;
        if (*dat == 0xFB) {
            zigbee_state = *(dat + 1);
            if (zigbee_state) {
                updateZigbeeShortAddress();
            }
            return;
        }
    }
    if (waiting_for_ZigbeeShortAddress) {
        waiting_for_ZigbeeShortAddress = 0;
        if (*dat == 0xFB) {
            HC_SetBeep(500);
            replyToTerminal(Pocket_Register, 2);
            LocalShortAddress = *(dat + 1) << 8 | *(dat + 2);
            *(replyPocketBuffer + 2) = LocalShortAddress >> 8;
            *(replyPocketBuffer + 3) = LocalShortAddress;
            return;
        }
    }
    if (*dat == 0xFF && *(dat + 1) == 0x00) {
        zigbee_state = 0;
        HC_SetBeep(50);
        return;
    }
    if (*dat == 0xFF && *(dat + 1) == 0xAA) {
        zigbee_state = 1;

        updateZigbeeShortAddress();
        return;
    }

    if (*dat == 0x55 && *(dat + 1) == 0x5A) {
        switch (*(dat + 2)) {
            case 0x01:
                sendAirDataToTerminal();
                break;
            case 0xAA:
                replyToTerminal(Pocket_Reply_Pulse, 2);
                break;
            case 0xAC:
                sendChargeStateToTerminal();
                break;
            case 0xAB:
                sendBatteryToTerminal();
                break;
            case 0xFF:
                if (pocket_len != 0) {
                    sendMessageUart1_DMA(ZigbeeMessageBuffer, pocket_len);
                } else {
                    replyToTerminal(Pocket_Invalid_Reply_Request, 2);
                }
                break;
            case 0xFE:
                isRegistered = 1;
                break;

        }
    }
}

void HC_1ms_Task_For_Sensor() {
    if (!isRegistered && zigbee_state && waiting_for_ZigbeeShortAddress == 0) {
        if (registerCoolDown != 0) {
            registerCoolDown--;
            return;
        }
        replyToTerminal(Pocket_Register, 2);
        registerCoolDown = 1000;
    }
}